home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / games / IndiZone / oort / dashboard.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  31.3 KB  |  1,448 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*------------------------------------------------------------------------------
  18.  * OORT - dashboard.c - Routines for drawing dashboard.
  19.  *
  20.  * $Id: dashboard.c,v 1.2 1994/01/28 00:17:21 mtj Exp $
  21.  *
  22.  * Chris Fouts - May, 1993.
  23.  *
  24.  *----------------------------------------------------------------------------*/
  25.  
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <stdarg.h>
  29. #include <string.h>
  30. #include <unistd.h>
  31. #include <math.h>
  32. #include <sys/param.h>
  33. #include <sys/types.h>
  34. #include <sys/stat.h>
  35. #include <fcntl.h>
  36. #include <bstring.h>
  37. #include <netinet/in.h>
  38. #include <netdb.h>
  39. #include <arpa/inet.h>
  40. #include <gl/device.h>
  41.  
  42. #include <pf.h>
  43.  
  44. #include "oort.h"
  45. #include "text.h"
  46. #include "radar.h"
  47. #include "gameio.h"
  48. #include "dashboard.h"
  49.  
  50. /* BEGIN PROTOTYPES -S dashboard.c */
  51. static void     drawFrames( void ) ;
  52. static void     drawOneFrame( pfVec3 tl, pfVec3 tr, pfVec3 bl, pfVec3 br,
  53.                     long topColor, long leftColor, long rightColor,
  54.                     long bottomColor ) ;
  55. static void     formatMessage( void ) ;
  56. static void     initTextScreen( void ) ;
  57. static void     interpVec3( pfVec3 a, float v, pfVec3 b, pfVec3 c ) ;
  58. static void     locateGauges( void ) ;
  59. static void     repaintDashboard( void ) ;
  60. static void     showHeading( void ) ;
  61. static void     showPlayers( void ) ;
  62. static void     showScores( void ) ;
  63. static void     showText( void ) ;
  64. /* END PROTOTYPES -S dashboard.c */
  65.  
  66.  
  67. #define    MAX_MSG_LINES    3
  68.  
  69. int            needToRepaint = 1 ;
  70. int            sendingMessage = 0 ;
  71. static int        textScreenLine = 0 ;
  72. static int        repaintTextScreen = 2 ;
  73. static int        repaintScores = 2 ;
  74. static int        repaintPlayers = 2 ;
  75. static char        textLines[MAX_TEXT_LINES][MAX_MSG_SIZE] ;
  76. static char        msgLines[MAX_MSG_LINES][MAX_MSG_SIZE] ;
  77. static char        message[MAX_MSG_SIZE] ;
  78. static int        nMsgLines ;
  79. static int        nMsgChars ;
  80. static int        reformatMessage = 0 ;
  81. static char        mailMode ;
  82.  
  83. BarGraph        speedometerBG ;
  84. BarGraph        shieldsBG ;
  85. BarGraph        powerBG ;
  86. BarGraph        laserBG ;
  87. BarGraph        cloakBG ;
  88.  
  89. extern int        nTextLines ;
  90. extern int        numberPlayers ;
  91. extern float        speed ;
  92. extern float        power ;
  93. extern float        shields ;
  94. extern float        laser ;
  95. extern float        cloak ;
  96. extern float        topSpeed ;
  97. extern ViewPort        radarVP ;
  98. extern pfLight        *Sun ;
  99. extern GeoFont        *helvFont ;
  100.  
  101. static ViewPort        dashboardVP ;
  102. static float        dashboardAR ;
  103. static int        dashboardFOV ;
  104. static float        dashboardAngle ;
  105. static float        dashboardNear = 0.1f ;
  106. static float        dashboardFar = 5.0f ;
  107. static GeoFont        *cf ;
  108. static GeoFont        *hf ;
  109. static GeoFont        *sf ;
  110. static float        textScreenH ;
  111. static float        textScreenW ;
  112. static float        textScreenFontSize ;
  113. static float        textScreenRotX ;
  114. static float        textScreenRotY ;
  115. static pfVec3        textScreenBL ;
  116. static pfVec3        textScreenBR ;
  117. static pfVec3        textScreenTL ;
  118. static pfVec3        textScreenTR ;
  119. static int        kills ;
  120. static int        lives ;
  121.  
  122.  
  123. static char        *compassLabel = "COMPASS" ;
  124. static char        *radarLabel = "RADAR" ;
  125. static char        *textScreenLabel = "INFO" ;
  126. static char        *livesLabel = "LIVES" ;
  127. static char        *killsLabel = "KILLS" ;
  128. static char        *playersLabel = "PLAYERS" ;
  129. static struct {
  130.     float    x ;
  131.     float    y ;
  132.     char    *text ;
  133.     } gaugeLabel[5] ;
  134.  
  135. static char    *gaugeText[] = {
  136.             "SPEED",
  137.             "SHIELD",
  138.             "POWER",
  139.             "LASER",
  140.             "ECM",
  141.             } ;
  142.  
  143.  
  144. static float    backPanel[][3] = {
  145.             { -9.00f, -0.5f, -1.5f },
  146.             { -9.00f, -1.0f, -1.2f },
  147.             { -1.13f, -0.5f, -1.5f },
  148.             { -1.00f, -1.0f, -1.2f },
  149.             { -0.42f, -0.5f, -2.0f },
  150.             { -0.29f, -1.0f, -1.7f },
  151.             {  0.42f, -0.5f, -2.0f },
  152.             {  0.29f, -1.0f, -1.7f },
  153.             {  1.12f, -0.5f, -1.5f },
  154.             {  1.00f, -1.0f, -1.2f },
  155.             {  9.00f, -0.5f, -1.5f },
  156.             {  9.00f, -1.0f, -1.2f },
  157.             } ;
  158.  
  159. static float    compassFrame[][3] = {
  160.             {  0.20f, -1.0f, -1.65f },
  161.             { -0.20f, -1.0f, -1.65f },
  162.             {  0.20f, -1.0f, -1.25f },
  163.             { -0.20f, -1.0f, -1.25f },
  164.             } ;
  165.  
  166. static float    killsFrame[][3] = {
  167.             { -0.30f, -1.0f, -1.35f },
  168.             { -0.50f, -1.0f, -1.35f },
  169.             { -0.30f, -1.0f, -1.25f },
  170.             { -0.50f, -1.0f, -1.25f },
  171.             } ;
  172.  
  173. static float    livesFrame[][3] = {
  174.             {  0.50f, -1.0f, -1.35f },
  175.             {  0.30f, -1.0f, -1.35f },
  176.             {  0.50f, -1.0f, -1.25f },
  177.             {  0.30f, -1.0f, -1.25f },
  178.             } ;
  179.  
  180. static float    playersFrame[][3] = {
  181.             {  0.10f, -1.0f, -1.15f },
  182.             { -0.10f, -1.0f, -1.15f },
  183.             {  0.10f, -1.0f, -1.05f },
  184.             { -0.10f, -1.0f, -1.05f },
  185.             } ;
  186.  
  187. static float    compassArrow[4][3] = {
  188.             {  0.04f, 0.0f,  0.04f },
  189.             {  0.00f, 0.0f, -0.14f },
  190.             {  0.00f, 0.0f,  0.00f },
  191.             { -0.04f, 0.0f,  0.04f },
  192.             } ;
  193.  
  194. static float    radarCorner[][3] = {
  195.             { -0.25f, -0.95f, -1.73f },
  196.             {  0.25f, -0.55f, -1.97f },
  197.             } ;
  198.  
  199. /*------------------------------------------------------------------------------
  200.  * Repaint the dashboard background.
  201.  *----------------------------------------------------------------------------*/
  202. static void
  203. repaintDashboard(
  204.     void
  205.     )
  206. {
  207.     int    i ;
  208.     float    c ;
  209.     float    s ;
  210.     pfVec2    p ;
  211.     pfVec3    v0 ;
  212.     pfVec3    v1 ;
  213.  
  214.     cpack( 0x00b0b0b0 ) ;
  215.     clear() ;
  216.  
  217.     /*
  218.      * Draw compass background.
  219.      */
  220.     cpack( 0x0 ) ;
  221.     bgntmesh() ;
  222.         v3f( compassFrame[0] ) ;
  223.         v3f( compassFrame[1] ) ;
  224.         v3f( compassFrame[2] ) ;
  225.         v3f( compassFrame[3] ) ;
  226.     endtmesh() ;
  227.  
  228.     pfPushMatrix() ;
  229.     translate( 0.0f, -1.0f, -1.45f ) ;
  230.     rot( -90.0f, 'x' ) ;
  231.     positionText( -0.5f * getStrWidth( hf, compassLabel ),
  232.             -0.22f - getFontSize( hf ) ) ;
  233.     drawString( hf, compassLabel ) ;
  234.     cpack( 0x00ffffff ) ;
  235.     bgnline() ;
  236.         for( i = 0 ; i <= 36 ; i++ )
  237.         {
  238.             pfSinCos( i * 10.0f, &s, &c ) ;
  239.             PFSET_VEC2( p, 0.18f * s, 0.18f * c ) ;
  240.             v2f( p ) ;
  241.         }
  242.     endline() ;
  243.     PFSET_VEC3( v0, 0.15f, 0.0f, 0.0f ) ;
  244.     PFSET_VEC3( v1, 0.18f, 0.0f, 0.0f ) ;
  245.     for( i = 0 ; i < 8 ; i++ )
  246.     {
  247.         bgnline() ;
  248.             v3f( v0 ) ;
  249.             v3f( v1 ) ;
  250.         endline() ;
  251.         rot( 45.0f, 'z' ) ;
  252.     }
  253.     pfPopMatrix() ;
  254.  
  255.     /*
  256.      * Draw left panel.
  257.      */
  258.     cpack( 0x00808080 ) ;
  259.     bgntmesh() ;
  260.         v3f( backPanel[0] ) ;
  261.         v3f( backPanel[1] ) ;
  262.         v3f( backPanel[2] ) ;
  263.         v3f( backPanel[3] ) ;
  264.         cpack( 0x00606060 ) ;
  265.         v3f( backPanel[4] ) ;
  266.         v3f( backPanel[5] ) ;
  267.         cpack( 0x00808080 ) ;
  268.         v3f( backPanel[6] ) ;
  269.         v3f( backPanel[7] ) ;
  270.         cpack( 0x00606060 ) ;
  271.         v3f( backPanel[8] ) ;
  272.         v3f( backPanel[9] ) ;
  273.         cpack( 0x00808080 ) ;
  274.         v3f( backPanel[10] ) ;
  275.         v3f( backPanel[11] ) ;
  276.     endtmesh() ;
  277.  
  278.     /*
  279.      * Label radar.
  280.      */
  281.     pfPushMatrix() ;
  282.     cpack( 0x0 ) ;
  283.     translate( 0.0f, radarCorner[0][1], radarCorner[0][2] ) ;
  284.     PFSUB_VEC3( v0, radarCorner[0], radarCorner[1] ) ;
  285.     rot( pfArcTan2( -v0[2], -v0[1] ), 'x' ) ;
  286.     positionText( -0.5f * getStrWidth( hf, radarLabel ),
  287.             -0.02f - getFontSize( hf ) ) ;
  288.     drawString( hf, radarLabel ) ;
  289.     pfPopMatrix() ;
  290.  
  291.     /*
  292.      * Label gauges.
  293.      */
  294.     pfPushMatrix() ;
  295.     translate( backPanel[7][0], backPanel[7][1], backPanel[7][2] ) ;
  296.     rot( -textScreenRotY, 'y' ) ;
  297.     rot( textScreenRotX, 'x' ) ;
  298.     cpack( 0x0 ) ;
  299.     for( i = 0 ; i < 5 ; i++ )
  300.     {
  301.         positionText( gaugeLabel[i].x, gaugeLabel[i].y ) ;
  302.         drawString( hf, gaugeLabel[i].text ) ;
  303.     }
  304.     pfPopMatrix() ;
  305.  
  306.     /*
  307.      * Label text screen.
  308.      */
  309.     pfPushMatrix() ;
  310.     translate( textScreenBL[0], textScreenBL[1], textScreenBL[2] ) ;
  311.     rot( textScreenRotY, 'y' ) ;
  312.     rot( textScreenRotX, 'x' ) ;
  313.     cpack( 0x0 ) ;
  314.     positionText( 0.5f*( textScreenW - getStrWidth( hf, textScreenLabel ) ),
  315.             -0.02f - getFontSize( hf ) ) ;
  316.     drawString( hf, textScreenLabel ) ;
  317.     pfPopMatrix() ;
  318.  
  319.     /*
  320.      * Label kill counter.
  321.      */
  322.     pfPushMatrix() ;
  323.     translate( -0.4f, -1.0f, -1.25f ) ;
  324.     rot( -90.0f, 'x' ) ;
  325.     positionText( -0.5f * getStrWidth( hf, killsLabel ),
  326.             -0.02f - getFontSize( hf ) ) ;
  327.     drawString( hf, killsLabel ) ;
  328.     pfPopMatrix() ;
  329.  
  330.     /*
  331.      * Label lives counter.
  332.      */
  333.     pfPushMatrix() ;
  334.     translate(  0.4f, -1.0f, -1.25f ) ;
  335.     rot( -90.0f, 'x' ) ;
  336.     positionText( -0.5f * getStrWidth( hf, livesLabel ),
  337.             -0.02f - getFontSize( hf ) ) ;
  338.     drawString( hf, livesLabel ) ;
  339.     pfPopMatrix() ;
  340.  
  341.     /*
  342.      * Label player counter.
  343.      */
  344.     pfPushMatrix() ;
  345.     translate( 0.0f, -1.0f, -1.05f ) ;
  346.     rot( -90.0f, 'x' ) ;
  347.     positionText( -0.5f * getStrWidth( hf, playersLabel ),
  348.             -0.02f - getFontSize( hf ) ) ;
  349.     drawString( hf, playersLabel ) ;
  350.     pfPopMatrix() ;
  351.  
  352.     drawFrames() ;
  353.  
  354.     repaintTextScreen = 2 ;
  355.     repaintScores = 2 ;
  356.     repaintPlayers = 2 ;
  357. }
  358.  
  359.  
  360.  
  361. /*------------------------------------------------------------------------------
  362.  * Set the position of the dashboard and radar.
  363.  *----------------------------------------------------------------------------*/
  364. void
  365. setDashboardPosition(
  366.     int    left,
  367.     int    right,
  368.     int    bottom,
  369.     int    top
  370.     )
  371. {
  372.     float        fovx ;
  373.     float        cotangent ;
  374.     float        c ;
  375.     float        s ;
  376.     float        cx ;
  377.     float        cy ;
  378.     float        sx ;
  379.     float        sy ;
  380.     pfVec4        pt ;
  381.     pfMatrix    m ;
  382.  
  383.     /*
  384.      * Determine location of dashboard.
  385.      */
  386.     dashboardVP.left = left ;
  387.     dashboardVP.right = right ;
  388.     dashboardVP.bottom = bottom ;
  389.     dashboardVP.top = top ;
  390.  
  391.     /*
  392.      * Determine aspect ratio and field of view for dashboard.
  393.      */
  394.     dashboardAR = (float)( dashboardVP.right - dashboardVP.left ) /
  395.             (float)( dashboardVP.top - dashboardVP.bottom ) ;
  396.     dashboardFOV = 320 ;
  397.     fovx = 2.0f * pfArcTan2( dashboardAR * pfTan( .05f * dashboardFOV ),
  398.         1.0f ) ;
  399.     if( fovx < 70.0f )
  400.     {
  401.         dashboardFOV = (int)( 20.0f *
  402.             pfArcTan2( pfTan( 70.f / 2.f ) / dashboardAR, 1.0f ) );
  403.     }
  404.     dashboardAngle = (float)dashboardFOV / 20.0f + pfArcTan2( 0.5f, 2.0f ) ;
  405.  
  406.     /*
  407.      * Build "projection" matrix for determining location of radar viewport.
  408.      */
  409.     pfSinCos( (float)dashboardFOV / 20.0f, &s, &c ) ;
  410.     cotangent = c / s ;
  411.     pfSinCos( dashboardAngle, &s, &c ) ;
  412.  
  413.     m[0][0] = cotangent / dashboardAR ;
  414.     m[0][1] = 0.0f ;
  415.     m[0][2] = 0.0f ;
  416.     m[0][3] = 0.0f ;
  417.  
  418.     m[1][0] = 0.0f ;
  419.     m[1][1] = cotangent * c ;
  420.     m[1][2] = -s * ( dashboardFar + dashboardNear ) /
  421.                 ( dashboardFar - dashboardNear ) ;
  422.     m[1][3] = -s ;
  423.  
  424.     m[2][0] = 0.0f ;
  425.     m[2][1] = -cotangent * s ;
  426.     m[2][2] = -c * ( dashboardFar + dashboardNear ) /
  427.                 ( dashboardFar - dashboardNear ) ;
  428.     m[2][3] = -c ;
  429.  
  430.     m[3][0] = 0.0f ;
  431.     m[3][1] = 0.0f ;
  432.     m[3][2] = -2.0f * ( dashboardFar * dashboardNear ) /
  433.                 ( dashboardFar - dashboardNear ) ;
  434.     m[3][3] = 0.0f ;
  435.  
  436.     /*
  437.      * Transform opposite corners of where radar is s'posed to be.
  438.      */
  439.     sx = 0.5 * ( dashboardVP.right - dashboardVP.left + 1.0 ) ;
  440.     sy = 0.5 * ( dashboardVP.top - dashboardVP.bottom + 1.0 ) ;
  441.     cx = 0.5 * ( dashboardVP.right + dashboardVP.left ) ;
  442.     cy = 0.5 * ( dashboardVP.top + dashboardVP.bottom ) ;
  443.  
  444.     pt[0] = radarCorner[0][0] ;
  445.     pt[1] = radarCorner[0][1] ;
  446.     pt[2] = radarCorner[0][2] ;
  447.     pt[3] = 1.0f ;
  448.     pfXformVec4( pt, pt, m ) ;
  449.  
  450.     pt[0] /= pt[3] ;
  451.     pt[1] /= pt[3] ;
  452.  
  453.     radarVP.left = (int)( pt[0] * sx + cx + 0.5 ) ;
  454.     radarVP.bottom = (int)( pt[1] * sy + cy + 0.5 ) ;
  455.  
  456.     pt[0] = radarCorner[1][0] ;
  457.     pt[1] = radarCorner[1][1] ;
  458.     pt[2] = radarCorner[1][2] ;
  459.     pt[3] = 1.0f ;
  460.     pfXformVec4( pt, pt, m ) ;
  461.  
  462.     pt[0] /= pt[3] ;
  463.     pt[1] /= pt[3] ;
  464.  
  465.     radarVP.right = (int)( pt[0] * sx + cx + 0.5 ) ;
  466.     radarVP.top = (int)( pt[1] * sy + cy + 0.5 ) ;
  467. }
  468.  
  469.  
  470.  
  471. /*------------------------------------------------------------------------------
  472.  * Show bar graph.
  473.  *----------------------------------------------------------------------------*/
  474. void
  475. showBarGraph(
  476.     BarGraph    *bar
  477.     )
  478. {
  479.     bgntmesh() ;
  480.         cpack( bar->fg ) ;
  481.         v3f( bar->v0 ) ;
  482.         v3f( bar->v1 ) ;
  483.         v3f( bar->v2 ) ;
  484.         v3f( bar->v3 ) ;
  485.         cpack( bar->bg ) ;
  486.         v3f( bar->v4 ) ;
  487.         v3f( bar->v5 ) ;
  488.     endtmesh() ;
  489. }
  490.  
  491.  
  492.  
  493. /*------------------------------------------------------------------------------
  494.  * Set the values of a bar graph.
  495.  *----------------------------------------------------------------------------*/
  496. void
  497. setBarGraph(
  498.     BarGraph    *bar,
  499.     float        value
  500.     )
  501. {
  502.     float    vm1 = 1.0f - value ;
  503.  
  504.     PFCOMBINE_VEC3( bar->v2, vm1, bar->v0, value, bar->v4 ) ;
  505.     PFCOMBINE_VEC3( bar->v3, vm1, bar->v1, value, bar->v5 ) ;
  506. }
  507.  
  508.  
  509.  
  510. /*------------------------------------------------------------------------------
  511.  * Initialize the locations of the guages.
  512.  *----------------------------------------------------------------------------*/
  513. static void
  514. locateGauges(
  515.     void
  516.     )
  517. {
  518.     int    gl = 0 ;
  519.     float    x ;
  520.     float    y ;
  521.     float    l ;
  522.     float    width = 0.10f ;
  523.     float    gap = 0.05f ;
  524.     float    fontSize ;
  525.     pfVec3    v ;
  526.     pfVec3    topBack ;
  527.     pfVec3    topFront ;
  528.     pfVec3    botBack ;
  529.     pfVec3    botFront ;
  530.     pfVec3    bottom ;
  531.     pfVec3    side ;
  532.  
  533.     /*
  534.      * Set up for locating gauges along right side.
  535.      */
  536.     PFSUB_VEC3( bottom, backPanel[9], backPanel[7] ) ;
  537.     PFSUB_VEC3( side, backPanel[6], backPanel[7] ) ;
  538.     PFCOPY_VEC3( v, side ) ;
  539.     pfNormalizeVec3( v ) ;
  540.     l = -PFDOT_VEC3( v, bottom ) ;
  541.     OFFSET_VEC3( side, l, bottom ) ;
  542.  
  543.     ADDSCALE_VEC3( botBack, backPanel[7], 0.15f, side ) ;
  544.     ADDSCALE_VEC3( topBack, backPanel[7], 0.90f, side ) ;
  545.  
  546.     ADDSCALE_VEC3( botFront, backPanel[9], 0.15f, side ) ;
  547.     ADDSCALE_VEC3( topFront, backPanel[9], 0.90f, side ) ;
  548.  
  549.     fontSize = 0.065f * PFLENGTH_VEC3( side ) ;
  550.     setFontSize( hf, fontSize ) ;
  551.     y = 0.5f * fontSize ;
  552.  
  553.     l = pfDistancePt3( botFront, botBack ) ;
  554.  
  555.     width = l / 6.0f ;
  556.     gap = width / 5.0f ;
  557.  
  558.     x = gap ;
  559.     /*
  560.      * Locate speedometer.
  561.      */
  562.     gaugeLabel[gl].x = x * l +
  563.         0.5f * ( l * width - getStrWidth( hf, gaugeText[gl] ) ) ;
  564.     gaugeLabel[gl].y = y ;
  565.     gaugeLabel[gl].text = gaugeText[gl] ;
  566.     gl++ ;
  567.     interpVec3( speedometerBG.v0, x, botBack, botFront ) ;
  568.     interpVec3( speedometerBG.v4, x, topBack, topFront ) ;
  569.     x += width ;
  570.     interpVec3( speedometerBG.v1, x, botBack, botFront ) ;
  571.     interpVec3( speedometerBG.v5, x, topBack, topFront ) ;
  572.     speedometerBG.fg = 0x000000ff ;
  573.     speedometerBG.bg = 0x00000000 ;
  574.     setBarGraph( &speedometerBG, 0.4f ) ;
  575.     x += gap ;
  576.  
  577.     /*
  578.      * Locate shields guage.
  579.      */
  580.     gaugeLabel[gl].x = x * l +
  581.         0.5f * ( l * width - getStrWidth( hf, gaugeText[gl] ) ) ;
  582.     gaugeLabel[gl].y = y ;
  583.     gaugeLabel[gl].text = gaugeText[gl] ;
  584.     gl++ ;
  585.     interpVec3( shieldsBG.v0, x, botBack, botFront ) ;
  586.     interpVec3( shieldsBG.v4, x, topBack, topFront ) ;
  587.     x += width ;
  588.     interpVec3( shieldsBG.v1, x, botBack, botFront ) ;
  589.     interpVec3( shieldsBG.v5, x, topBack, topFront ) ;
  590.     shieldsBG.fg = 0x000000ff ;
  591.     shieldsBG.bg = 0x00000000 ;
  592.     setBarGraph( &shieldsBG, 0.8f ) ;
  593.     x += gap ;
  594.  
  595.     /*
  596.      * Locate power guage.
  597.      */
  598.     gaugeLabel[gl].x = x * l +
  599.         0.5f * ( l * width - getStrWidth( hf, gaugeText[gl] ) ) ;
  600.     gaugeLabel[gl].y = y ;
  601.     gaugeLabel[gl].text = gaugeText[gl] ;
  602.     gl++ ;
  603.     interpVec3( powerBG.v0, x, botBack, botFront ) ;
  604.     interpVec3( powerBG.v4, x, topBack, topFront ) ;
  605.     x += width ;
  606.     interpVec3( powerBG.v1, x, botBack, botFront ) ;
  607.     interpVec3( powerBG.v5, x, topBack, topFront ) ;
  608.     powerBG.fg = 0x000000ff ;
  609.     powerBG.bg = 0x00000000 ;
  610.     setBarGraph( &powerBG, 0.8f ) ;
  611.     x += gap ;
  612.  
  613.     /*
  614.      * Locate laser guage.
  615.      */
  616.     gaugeLabel[gl].x = x * l +
  617.         0.5f * ( l * width - getStrWidth( hf, gaugeText[gl] ) ) ;
  618.     gaugeLabel[gl].y = y ;
  619.     gaugeLabel[gl].text = gaugeText[gl] ;
  620.     gl++ ;
  621.     interpVec3( laserBG.v0, x, botBack, botFront ) ;
  622.     interpVec3( laserBG.v4, x, topBack, topFront ) ;
  623.     x += width ;
  624.     interpVec3( laserBG.v1, x, botBack, botFront ) ;
  625.     interpVec3( laserBG.v5, x, topBack, topFront ) ;
  626.     laserBG.fg = 0x000000ff ;
  627.     laserBG.bg = 0x00000000 ;
  628.     setBarGraph( &laserBG, 0.8f ) ;
  629.     x += gap ;
  630.  
  631.     /*
  632.      * Locate cloak guage.
  633.      */
  634.     gaugeLabel[gl].x = x * l +
  635.         0.5f * ( l * width - getStrWidth( hf, gaugeText[gl] ) ) ;
  636.     gaugeLabel[gl].y = y ;
  637.     gaugeLabel[gl].text = gaugeText[gl] ;
  638.     gl++ ;
  639.     interpVec3( cloakBG.v0, x, botBack, botFront ) ;
  640.     interpVec3( cloakBG.v4, x, topBack, topFront ) ;
  641.     x += width ;
  642.     interpVec3( cloakBG.v1, x, botBack, botFront ) ;
  643.     interpVec3( cloakBG.v5, x, topBack, topFront ) ;
  644.     cloakBG.fg = 0x000000ff ;
  645.     cloakBG.bg = 0x00000000 ;
  646.     setBarGraph( &cloakBG, 0.0f ) ;
  647.     x += gap ;
  648. }
  649.  
  650.  
  651.  
  652. /*------------------------------------------------------------------------------
  653.  * Interpret between two points: a = v * b + ( 1 - v ) * c.
  654.  *----------------------------------------------------------------------------*/
  655. static void
  656. interpVec3(
  657.     pfVec3    a,
  658.     float    v,
  659.     pfVec3    b,
  660.     pfVec3    c
  661.     )
  662. {
  663.     float    vm = 1.0f - v ;
  664.  
  665.     PFCOMBINE_VEC3( a, vm, b, v, c ) ;
  666. }
  667.  
  668.  
  669.  
  670. /*------------------------------------------------------------------------------
  671.  * Show the text output area.
  672.  *----------------------------------------------------------------------------*/
  673. static void
  674. showText(
  675.     void
  676.     )
  677. {
  678.     int    i ;
  679.     int    n ;
  680.     float    x ;
  681.     float    y ;
  682.  
  683.     pfPushMatrix() ;
  684.     translate( textScreenBL[0], textScreenBL[1], textScreenBL[2] ) ;
  685.     rot( textScreenRotY, 'y' ) ;
  686.     rot( textScreenRotX, 'x' ) ;
  687.     cpack( 0x0 ) ;
  688.     rectf( 0.0f, 0.0f, textScreenW, textScreenH ) ;
  689.     x = 0.1f * textScreenFontSize ;
  690.     y = 0.1f * textScreenFontSize ;
  691.  
  692.     if( reformatMessage )
  693.     {
  694.         formatMessage() ;
  695.         reformatMessage = 0 ;
  696.     }
  697.  
  698.     cpack( 0x0000ffff ) ;
  699.     for( i = nMsgLines - 1 ; i >= 0 ; i-- )
  700.     {
  701.         positionText( x, y ) ;
  702.         drawString( cf, msgLines[i] ) ;
  703.         y += textScreenFontSize ;
  704.     }
  705.     cpack( 0x000000ff ) ;
  706.     for( i = 0 ; i < nTextLines - nMsgLines ; i++ )
  707.     {
  708.         n = ( textScreenLine + i ) % nTextLines ;
  709.         positionText( x, y ) ;
  710.         drawString( cf, textLines[n] ) ;
  711.         y += textScreenFontSize ;
  712.     }
  713.     pfPopMatrix() ;
  714. }
  715.  
  716.  
  717.  
  718. /*------------------------------------------------------------------------------
  719.  * Initialize dashboard stuff.
  720.  *----------------------------------------------------------------------------*/
  721. void
  722. initDashboard(
  723.     void
  724.     )
  725. {
  726.     cf = loadFont( "c.oort" ) ;
  727.  
  728.     hf = copyFont( helvFont ) ;
  729.  
  730.     sf = copyFont( hf ) ;
  731.     setFontSize( sf, 0.09f ) ;
  732.  
  733.     locateGauges() ;
  734.  
  735.     initTextScreen() ;
  736. }
  737.  
  738.  
  739.  
  740. /*------------------------------------------------------------------------------
  741.  * Dashboard draw callback.
  742.  *----------------------------------------------------------------------------*/
  743. void
  744. drawDashboardChannel(
  745.     pfChannel    *channel,
  746.     void        *data
  747.     )
  748. {
  749.     pfPushState() ;
  750.  
  751.     pfBasicState() ;
  752.  
  753.     pfLightOff( Sun ) ;
  754.  
  755.     zfunction( ZF_ALWAYS ) ;
  756.         zwritemask( 0x0 ) ;
  757.  
  758.     pfShadeModel( PFSM_FLAT ) ;
  759.  
  760.     viewport( dashboardVP.left, dashboardVP.right, dashboardVP.bottom,
  761.         dashboardVP.top ) ;
  762.     pfPushIdentMatrix() ;
  763.     perspective( dashboardFOV, dashboardAR, dashboardNear, dashboardFar ) ;
  764.     rot( dashboardAngle, 'x' ) ;
  765.  
  766.     if( needToRepaint )
  767.     {
  768.         needToRepaint = 0 ;
  769.         frontbuffer( 1 ) ;
  770.         repaintDashboard() ;
  771.         frontbuffer( 0 ) ;
  772.     }
  773.  
  774.     /*
  775.      * Update gauges.
  776.      */
  777.     if( speed < 0.0f )
  778.     {
  779.         speedometerBG.fg = 0x000000ff ;
  780.         setBarGraph( &speedometerBG, -speed / topSpeed ) ;
  781.     }
  782.     else
  783.     {
  784.         speedometerBG.fg = 0x0000ff00 ;
  785.         setBarGraph( &speedometerBG, speed / topSpeed ) ;
  786.     }
  787.     showBarGraph( &speedometerBG ) ;
  788.  
  789.     if( shields > 0.50f )
  790.         shieldsBG.fg = 0x0000ff00 ;
  791.     else if( shields > 0.25f )
  792.         shieldsBG.fg = 0x0000ffff ;
  793.     else
  794.         shieldsBG.fg = 0x000000ff ;
  795.     setBarGraph( &shieldsBG, shields ) ;
  796.     showBarGraph( &shieldsBG ) ;
  797.  
  798.     if( power > 0.50f )
  799.         powerBG.fg = 0x0000ff00 ;
  800.     else if( power > 0.25f )
  801.         powerBG.fg = 0x0000ffff ;
  802.     else
  803.         powerBG.fg = 0x000000ff ;
  804.     setBarGraph( &powerBG, power ) ;
  805.     showBarGraph( &powerBG ) ;
  806.  
  807.     setBarGraph( &laserBG, laser ) ;
  808.     showBarGraph( &laserBG ) ;
  809.  
  810.     setBarGraph( &cloakBG, cloak ) ;
  811.     showBarGraph( &cloakBG ) ;
  812.  
  813.     if( repaintTextScreen > 0 )
  814.     {
  815.         showText() ;
  816.         repaintTextScreen-- ;
  817.     }
  818.  
  819.     if( repaintScores > 0 )
  820.     {
  821.         showScores() ;
  822.         repaintScores-- ;
  823.     }
  824.  
  825.     if( repaintPlayers > 0 )
  826.     {
  827.         showPlayers() ;
  828.         repaintPlayers-- ;
  829.     }
  830.  
  831.     showHeading() ;
  832.     pfPopMatrix() ;
  833.  
  834.     pfPushIdentMatrix() ;
  835.     showRadar() ;
  836.     pfPopMatrix() ;
  837.  
  838.     zfunction( ZF_LEQUAL ) ;
  839.     zwritemask( 0xffffffff ) ;
  840.  
  841.     pfPopState() ;
  842. }
  843.  
  844.  
  845.  
  846. /*------------------------------------------------------------------------------
  847.  * Show the compass heading.
  848.  *----------------------------------------------------------------------------*/
  849. static void
  850. showHeading(
  851.     void
  852.     )
  853. {
  854.     static int    buf = 0 ;
  855.     static float    lastHeading[2] = { 0.0f, 0.0f } ;
  856.  
  857.     pfPushState();
  858.     pfBasicState();
  859.  
  860.     pfPushMatrix() ;
  861.     translate( 0.0f, -1.0f, -1.45f ) ;
  862.  
  863.     /*
  864.      * Erase previous arrow.
  865.      */
  866.     pfPushMatrix() ;
  867.     rot( lastHeading[buf], 'y' ) ;
  868.     cpack( 0x0 ) ;
  869.     bgntmesh() ;
  870.         v3f( compassArrow[0] ) ;
  871.         v3f( compassArrow[1] ) ;
  872.         v3f( compassArrow[2] ) ;
  873.         v3f( compassArrow[3] ) ;
  874.     endtmesh() ;
  875.     pfPopMatrix() ;
  876.  
  877.     /*
  878.      * Draw current arrow.
  879.      */
  880.     lastHeading[buf] = -getHeading() ;
  881.     rot( lastHeading[buf], 'y' ) ;
  882.     cpack( 0x000000ff ) ;
  883.     bgntmesh() ;
  884.         v3f( compassArrow[0] ) ;
  885.         v3f( compassArrow[1] ) ;
  886.         v3f( compassArrow[2] ) ;
  887.         v3f( compassArrow[3] ) ;
  888.     endtmesh() ;
  889.  
  890.     buf = ( buf + 1 ) % 2 ;
  891.  
  892.     pfPopMatrix() ;
  893.     pfPopState();
  894. }
  895.  
  896.  
  897.  
  898. /*------------------------------------------------------------------------------
  899.  * Initialize stuff for the text screen.
  900.  *----------------------------------------------------------------------------*/
  901. static void
  902. initTextScreen(
  903.     void
  904.     )
  905. {
  906.     int    i ;
  907.     float    d ;
  908.     pfVec3    a ;
  909.     pfVec3    up ;
  910.     pfVec3    v35 ;
  911.     pfVec3    bottom ;
  912.     pfVec3    side ;
  913.     pfVec3    v ;
  914.  
  915.     /*
  916.      * Set up for locating gauges along left side.
  917.      */
  918.     PFSUB_VEC3( bottom, backPanel[5], backPanel[3] ) ;
  919.     PFSUB_VEC3( side, backPanel[2], backPanel[3] ) ;
  920.     PFCOPY_VEC3( v, side ) ;
  921.  
  922.     pfNormalizeVec3( bottom ) ;
  923.     d = -PFDOT_VEC3( bottom, side ) ;
  924.     OFFSET_VEC3( side, d, bottom );
  925.     pfNormalizeVec3( side ) ;
  926.  
  927.     textScreenW = 0.80f * pfDistancePt3( backPanel[3], backPanel[5] ) ;
  928.     textScreenH = 0.80f * PFDOT_VEC3( v, side ) ;
  929.  
  930.     textScreenFontSize = textScreenH / (float)nTextLines ;
  931.  
  932.     setFontSize( cf, textScreenFontSize ) ;
  933.  
  934.     textScreenRotY = pfArcTan2( -bottom[2], bottom[0] ) ;
  935.  
  936.     pfCrossVec3( v, bottom, side ) ;
  937.     textScreenRotX = pfArcSin( -v[1] ) ;
  938.  
  939.     ADDSCALE_VEC3( textScreenBL, backPanel[3], 0.15f * textScreenW,
  940.             bottom ) ;
  941.     ADDSCALE_VEC3( textScreenBL, textScreenBL, 0.15f * textScreenH,
  942.             side ) ;
  943.  
  944.     ADDSCALE_VEC3( textScreenBR, textScreenBL, textScreenW, bottom );
  945.     ADDSCALE_VEC3( textScreenTL, textScreenBL, textScreenH, side ) ;
  946.     ADDSCALE_VEC3( textScreenTR, textScreenTL, textScreenW, bottom );
  947.  
  948.     for( i = 0 ; i < nTextLines ; i++ )
  949.     {
  950.         textLines[i][0] = '\0' ;
  951.     }
  952. }
  953.  
  954.  
  955.  
  956. /*------------------------------------------------------------------------------
  957.  * Post a new message to the text screen.
  958.  *----------------------------------------------------------------------------*/
  959. void
  960. postNewMessage(
  961.     char *fmt,
  962.     ...
  963.     )
  964. {
  965.     va_list        args ;
  966.     int        ncSeen ;
  967.     int        i ;
  968.     int        start = 0 ;
  969.     char        msg[512] ;
  970.  
  971.     va_start( args, fmt ) ;
  972.     vsprintf( msg, fmt, args ) ;
  973.  
  974.     ncSeen = maxCharsInWidth( cf, msg, textScreenW ) ;
  975.  
  976.     if( ncSeen < 1 )
  977.         return ;
  978.  
  979.     while( strlen( msg+start ) > ncSeen )
  980.     {
  981.         for( i = ncSeen ; i > 0 && msg[start+i] != ' ' ; i-- )
  982.         {
  983.         }
  984.  
  985.         textScreenLine = ( textScreenLine + nTextLines - 1 )
  986.                       % nTextLines ;
  987.         if( i == 0 )
  988.         {
  989.             i = ncSeen ;
  990.         }
  991.         strncpy( textLines[textScreenLine], msg+start, i ) ;
  992.         textLines[textScreenLine][i] = '\0' ;
  993.  
  994.         start += i ;
  995.     }
  996.  
  997.     if( msg[start] != '\0' )
  998.     {
  999.         textScreenLine = ( textScreenLine + nTextLines - 1 )
  1000.                       % nTextLines ;
  1001.         strncpy( textLines[textScreenLine], msg+start, MAX_MSG_SIZE ) ;
  1002.     }
  1003.     repaintTextScreen = 2 ;
  1004.  
  1005.     va_end( args ) ;
  1006. }
  1007.  
  1008.  
  1009.  
  1010. /*------------------------------------------------------------------------------
  1011.  * Draw frames around all of the gauges.
  1012.  *----------------------------------------------------------------------------*/
  1013. static void
  1014. drawFrames(
  1015.     void
  1016.     )
  1017. {
  1018.     pfVec3    tl ;
  1019.     pfVec3    tr ;
  1020.     pfVec3    bl ;
  1021.     pfVec3    br ;
  1022.     long    dark0 = 0x00101010 ;
  1023.     long    dark1 = 0x00202020 ;
  1024.     long    dark2 = 0x00404040 ;
  1025.     long    dark3 = 0x00707070 ;
  1026.     long    dark4 = 0x00a0a0a0 ;
  1027.     long    none = -1 ;
  1028.  
  1029.     /*
  1030.      * Radar frame.
  1031.      */
  1032.     PFSET_VEC3( tl, radarCorner[0][0], radarCorner[1][1],
  1033.             radarCorner[1][2] );
  1034.     PFSET_VEC3( tr, radarCorner[1][0], radarCorner[1][1],
  1035.             radarCorner[1][2] );
  1036.     PFSET_VEC3( bl, radarCorner[0][0], radarCorner[0][1],
  1037.             radarCorner[0][2] );
  1038.     PFSET_VEC3( br, radarCorner[1][0], radarCorner[0][1],
  1039.             radarCorner[0][2] );
  1040.     drawOneFrame( tl, tr, bl, br, dark1, dark2, dark2, dark4 ) ;
  1041.  
  1042.     /*
  1043.      * Bar graph frames.
  1044.      */
  1045.     drawOneFrame( speedometerBG.v4, speedometerBG.v5, speedometerBG.v0,
  1046.             speedometerBG.v1, dark0, dark1, none, dark4 ) ;
  1047.     drawOneFrame( shieldsBG.v4, shieldsBG.v5, shieldsBG.v0,
  1048.             shieldsBG.v1, dark0, dark1, none, dark4 ) ;
  1049.     drawOneFrame( powerBG.v4, powerBG.v5, powerBG.v0,
  1050.             powerBG.v1, dark0, dark1, none, dark4 ) ;
  1051.     drawOneFrame( laserBG.v4, laserBG.v5, laserBG.v0,
  1052.             laserBG.v1, dark0, dark1, none, dark4 ) ;
  1053.     drawOneFrame( cloakBG.v4, cloakBG.v5, cloakBG.v0,
  1054.             cloakBG.v1, dark0, dark1, none, dark4 ) ;
  1055.  
  1056.     /*
  1057.      * Text screen frame.
  1058.      */
  1059.     drawOneFrame( textScreenTL, textScreenTR, textScreenBL,
  1060.             textScreenBR, dark0, none, dark2, dark4 ) ;
  1061.  
  1062.     /*
  1063.      * Compass frame.
  1064.      */
  1065.     drawOneFrame( compassFrame[1], compassFrame[0], compassFrame[3],
  1066.             compassFrame[2], dark2, dark3, dark3, none ) ;
  1067.  
  1068.     /*
  1069.      * Kill counter frame.
  1070.      */
  1071.     drawOneFrame( killsFrame[1], killsFrame[0], killsFrame[3],
  1072.             killsFrame[2], dark2, dark3, dark3, none ) ;
  1073.  
  1074.     /*
  1075.      * Life counter frame.
  1076.      */
  1077.     drawOneFrame( livesFrame[1], livesFrame[0], livesFrame[3],
  1078.             livesFrame[2], dark2, dark3, dark3, none ) ;
  1079.  
  1080.     /*
  1081.      * Player counter frame.
  1082.      */
  1083.     drawOneFrame( playersFrame[1], playersFrame[0], playersFrame[3],
  1084.             playersFrame[2], dark2, dark3, dark3, none ) ;
  1085. }
  1086.  
  1087.  
  1088.  
  1089. /*------------------------------------------------------------------------------
  1090.  * Draw a frame.
  1091.  *----------------------------------------------------------------------------*/
  1092. static void
  1093. drawOneFrame(
  1094.     pfVec3    tl,
  1095.     pfVec3    tr,
  1096.     pfVec3    bl,
  1097.     pfVec3    br,
  1098.     long    topColor,
  1099.     long    leftColor,
  1100.     long    rightColor,
  1101.     long    bottomColor
  1102.     )
  1103. {
  1104.     float    dl ;
  1105.     float    dr ;
  1106.     float    dt ;
  1107.     float    db ;
  1108.     pfVec3    otl ;
  1109.     pfVec3    otr ;
  1110.     pfVec3    obl ;
  1111.     pfVec3    obr ;
  1112.     pfVec3    v ;
  1113.     pfVec3    h ;
  1114.     pfVec3    u ;
  1115.  
  1116.     PFSUB_VEC3( v, tl, bl ) ;
  1117.     pfNormalizeVec3( v ) ;
  1118.     PFSUB_VEC3( h, tr, tl ) ;
  1119.     pfNormalizeVec3( h ) ;
  1120.     pfCrossVec3( u, h, v ) ;
  1121.     PFSCALE_VEC3( u, 0.005f, u ) ;
  1122.  
  1123.     dl = ( leftColor == -1 ) ? 0.0f : -0.01f ;
  1124.     dr = ( rightColor == -1 ) ? 0.0f : 0.01f ;
  1125.     dt = ( topColor == -1 ) ? 0.0f : 0.01f ;
  1126.     db = ( bottomColor == -1 ) ? 0.0f : -0.01f ;
  1127.  
  1128.     PFCOMBINE_VEC3( otl, dl, h, dt, v ) ;
  1129.     PFADD_VEC3( otl, otl, tl ) ;
  1130.     PFADD_VEC3( otl, otl, u ) ;
  1131.  
  1132.     PFCOMBINE_VEC3( otr, dr, h, dt, v ) ;
  1133.     PFADD_VEC3( otr, otr, tr ) ;
  1134.     PFADD_VEC3( otr, otr, u ) ;
  1135.  
  1136.     PFCOMBINE_VEC3( obl, dl, h, db, v ) ;
  1137.     PFADD_VEC3( obl, obl, bl ) ;
  1138.     PFADD_VEC3( obl, obl, u ) ;
  1139.  
  1140.     PFCOMBINE_VEC3( obr, dr, h, db, v ) ;
  1141.     PFADD_VEC3( obr, obr, br ) ;
  1142.     PFADD_VEC3( obr, obr, u ) ;
  1143.  
  1144.     if( leftColor != -1 )
  1145.     {
  1146.         cpack( leftColor ) ;
  1147.         bgntmesh() ;
  1148.             v3f( obl ) ;
  1149.             v3f( bl ) ;
  1150.             v3f( otl ) ;
  1151.             v3f( tl ) ;
  1152.         endtmesh() ;
  1153.     }
  1154.  
  1155.     if( rightColor != -1 )
  1156.     {
  1157.         cpack( rightColor ) ;
  1158.         bgntmesh() ;
  1159.             v3f( br ) ;
  1160.             v3f( obr ) ;
  1161.             v3f( tr ) ;
  1162.             v3f( otr ) ;
  1163.         endtmesh() ;
  1164.     }
  1165.  
  1166.     if( topColor != -1 )
  1167.     {
  1168.         cpack( topColor ) ;
  1169.         bgntmesh() ;
  1170.             v3f( otl ) ;
  1171.             v3f( tl ) ;
  1172.             v3f( otr ) ;
  1173.             v3f( tr ) ;
  1174.         endtmesh() ;
  1175.     }
  1176.  
  1177.     if( bottomColor != -1 )
  1178.     {
  1179.         cpack( bottomColor ) ;
  1180.         bgntmesh() ;
  1181.             v3f( bl ) ;
  1182.             v3f( obl ) ;
  1183.             v3f( br ) ;
  1184.             v3f( obr ) ;
  1185.         endtmesh() ;
  1186.     }
  1187. }
  1188.  
  1189.  
  1190.  
  1191. /*------------------------------------------------------------------------------
  1192.  * Prepare to send a message.
  1193.  *----------------------------------------------------------------------------*/
  1194. void
  1195. initMessage(
  1196.     char    mode
  1197.     )
  1198. {
  1199.     mailMode = mode ;
  1200.     if( mode == MAIL_ALL )
  1201.     {
  1202.         postNewMessage( "Enter message:" ) ;
  1203.     }
  1204.     else
  1205.     {
  1206.         postNewMessage( "Enter team message:" ) ;
  1207.     }
  1208.     sendingMessage = 1 ;
  1209.     nMsgChars = 0 ;
  1210.     message[nMsgChars] = '_' ;
  1211.     message[nMsgChars+1] = '\0' ;
  1212.     nMsgLines = 1 ;
  1213.     repaintTextScreen = 2 ;
  1214.     reformatMessage = 1 ;
  1215. }
  1216.  
  1217.  
  1218.  
  1219. /*------------------------------------------------------------------------------
  1220.  * Add to the message.
  1221.  *----------------------------------------------------------------------------*/
  1222. void
  1223. addToMessage(
  1224.     char    c
  1225.     )
  1226. {
  1227.     if( c == '\010' )
  1228.     {
  1229.         if( nMsgChars > 0 )
  1230.         {
  1231.             message[--nMsgChars] = '_' ;
  1232.             message[nMsgChars+1] = '\0' ;
  1233.             repaintTextScreen = 2 ;
  1234.             reformatMessage = 1 ;
  1235.         }
  1236.     }
  1237.     else if( c == '\015' )
  1238.     {
  1239.         sendingMessage = 0 ;
  1240.         message[nMsgChars] = '\0' ;
  1241.         if( mailMode == MAIL_ALL )
  1242.         {
  1243.             postNewMessage( "Message sent." ) ;
  1244.         }
  1245.         else
  1246.         {
  1247.             postNewMessage( "Team message sent." ) ;
  1248.         }
  1249.         nMsgLines = 0 ;
  1250.         if( nMsgChars )
  1251.         {
  1252.             mailMessage( mailMode, message ) ;
  1253.         }
  1254.     }
  1255.     else if( nMsgChars < MAX_MSG_SIZE - 1 )
  1256.     {
  1257.         repaintTextScreen = 2 ;
  1258.         reformatMessage = 1 ;
  1259.  
  1260.         message[nMsgChars++] = c ;
  1261.         if( nMsgChars < MAX_MSG_SIZE - 1 )
  1262.         {
  1263.             message[nMsgChars] = '_' ;
  1264.             message[nMsgChars+1] = '\0' ;
  1265.         }
  1266.         else
  1267.         {
  1268.             message[nMsgChars] = '\0' ;
  1269.         }
  1270.     }
  1271. }
  1272.  
  1273.  
  1274.  
  1275. /*------------------------------------------------------------------------------
  1276.  * Format the message.
  1277.  *----------------------------------------------------------------------------*/
  1278. static void
  1279. formatMessage(
  1280.     void
  1281.     )
  1282. {
  1283.     int        ncSeen ;
  1284.     int        i ;
  1285.     int        start = 0 ;
  1286.  
  1287.     ncSeen = maxCharsInWidth( cf, message, textScreenW ) ;
  1288.  
  1289.     nMsgLines = 0 ;
  1290.  
  1291.     if( ncSeen < 1 )
  1292.     {
  1293.         msgLines[nMsgLines][0] = '\0' ;
  1294.         return ;
  1295.     }
  1296.  
  1297.     while( strlen( message+start ) > ncSeen && nMsgLines < MAX_MSG_LINES )
  1298.     {
  1299.         for( i = ncSeen ; i > 0 && message[start+i] != ' ' ; i-- )
  1300.         {
  1301.         }
  1302.  
  1303.         if( i == 0 )
  1304.         {
  1305.             i = ncSeen ;
  1306.         }
  1307.         strncpy( msgLines[nMsgLines], message+start, i ) ;
  1308.         msgLines[nMsgLines][i] = '\0' ;
  1309.         nMsgLines++ ;
  1310.  
  1311.         start += i ;
  1312.     }
  1313.  
  1314.     if( message[start] != '\0' && nMsgLines < MAX_MSG_LINES )
  1315.     {
  1316.         strncpy( msgLines[nMsgLines], message+start, MAX_MSG_SIZE ) ;
  1317.         nMsgLines++ ;
  1318.     }
  1319. }
  1320.  
  1321.  
  1322.  
  1323. /*------------------------------------------------------------------------------
  1324.  * Draw kills and lives counters.
  1325.  *----------------------------------------------------------------------------*/
  1326. static void
  1327. showScores(
  1328.     void
  1329.     )
  1330. {
  1331.     char    str[10] ;
  1332.  
  1333.     cpack( 0x0 ) ;
  1334.  
  1335.     /*
  1336.      * Draw kills counter background.
  1337.      */
  1338.     bgntmesh() ;
  1339.         v3f( killsFrame[0] ) ;
  1340.         v3f( killsFrame[1] ) ;
  1341.         v3f( killsFrame[2] ) ;
  1342.         v3f( killsFrame[3] ) ;
  1343.     endtmesh() ;
  1344.  
  1345.     /*
  1346.      * Draw lives counter background.
  1347.      */
  1348.     bgntmesh() ;
  1349.         v3f( livesFrame[0] ) ;
  1350.         v3f( livesFrame[1] ) ;
  1351.         v3f( livesFrame[2] ) ;
  1352.         v3f( livesFrame[3] ) ;
  1353.     endtmesh() ;
  1354.  
  1355.     pfPushMatrix() ;
  1356.     cpack( 0x00ffffff ) ;
  1357.     translate( killsFrame[2][0], killsFrame[2][1], killsFrame[2][2] ) ;
  1358.     rot( -90.0f, 'x' ) ;
  1359.     sprintf( str, "%d", kills ) ;
  1360.     positionText( -0.01f - getStrWidth( sf, str ), 0.0f ) ;
  1361.     drawString( sf, str ) ;
  1362.     pfPopMatrix() ;
  1363.  
  1364.     pfPushMatrix() ;
  1365.     cpack( 0x00ffffff ) ;
  1366.     translate( livesFrame[2][0], livesFrame[2][1], livesFrame[2][2] ) ;
  1367.     rot( -90.0f, 'x' ) ;
  1368.     sprintf( str, "%d", lives ) ;
  1369.     positionText( -0.01f - getStrWidth( sf, str ), 0.0f ) ;
  1370.     drawString( sf, str ) ;
  1371.     pfPopMatrix() ;
  1372. }
  1373.  
  1374.  
  1375.  
  1376. /*------------------------------------------------------------------------------
  1377.  * Increment the kill counter.
  1378.  *----------------------------------------------------------------------------*/
  1379. void
  1380. addKill(
  1381.     void
  1382.     )
  1383. {
  1384.     kills++ ;
  1385.     repaintScores = 2 ;
  1386. }
  1387.  
  1388.  
  1389.  
  1390. /*------------------------------------------------------------------------------
  1391.  * Increment the life counter.
  1392.  *----------------------------------------------------------------------------*/
  1393. void
  1394. addLife(
  1395.     void
  1396.     )
  1397. {
  1398.     lives++ ;
  1399.     repaintScores = 2 ;
  1400. }
  1401.  
  1402.  
  1403.  
  1404. /*------------------------------------------------------------------------------
  1405.  * Draw player counters.
  1406.  *----------------------------------------------------------------------------*/
  1407. static void
  1408. showPlayers(
  1409.     void
  1410.     )
  1411. {
  1412.     char    str[10] ;
  1413.  
  1414.     cpack( 0x0 ) ;
  1415.  
  1416.     /*
  1417.      * Draw players counter background.
  1418.      */
  1419.     bgntmesh() ;
  1420.         v3f( playersFrame[0] ) ;
  1421.         v3f( playersFrame[1] ) ;
  1422.         v3f( playersFrame[2] ) ;
  1423.         v3f( playersFrame[3] ) ;
  1424.     endtmesh() ;
  1425.  
  1426.     pfPushMatrix() ;
  1427.     cpack( 0x00ffffff ) ;
  1428.     translate( playersFrame[2][0], playersFrame[2][1], playersFrame[2][2] );
  1429.     rot( -90.0f, 'x' ) ;
  1430.     sprintf( str, "%d", numberPlayers ) ;
  1431.     positionText( -0.01f - getStrWidth( sf, str ), 0.0f ) ;
  1432.     drawString( sf, str ) ;
  1433.     pfPopMatrix() ;
  1434. }
  1435.  
  1436.  
  1437.  
  1438. /*------------------------------------------------------------------------------
  1439.  * Trigger player counter repaint.
  1440.  *----------------------------------------------------------------------------*/
  1441. void
  1442. updatePlayerCounter(
  1443.     void
  1444.     )
  1445. {
  1446.     repaintPlayers = 2 ;
  1447. }
  1448.